﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text.RegularExpressions;
using Windows.ApplicationModel.DataTransfer;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using 纸片人.UtilFolter;
using 纸片人.win2dEffectControl;
using 纸片人.win2dEffectControl.DataClass;

// The Templated Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234235

namespace 纸片人.CalculateControls
{
    public abstract class RangeControl : CalculateControl
    {


        #region 属性
        public object Header    
        {
            get { return (object)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Header.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HeaderProperty =
            DependencyProperty.Register("Header", typeof(object), typeof(RangeControl), new PropertyMetadata(null, OnHeaderChanged));

        private static void OnHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is RangeControl rc && e.NewValue != e.OldValue)
            {
                rc.OnHeaderChanged(e.NewValue, e.OldValue);
            }
        }
        protected virtual void OnHeaderChanged(object newValue, object oldValue)
        {
        }



        /// <summary>
        /// 获取或设置Maximum的值
        /// </summary>  
        public double Maximum
        {
            get { return (double)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }

        /// <summary>
        /// 标识 Maximum 依赖属性。
        /// </summary>
        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.Register("Maximum", typeof(double), typeof(RangeControl), new PropertyMetadata(double.PositiveInfinity, OnMaximumChanged));

        private static void OnMaximumChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            RangeControl target = obj as RangeControl;
            double oldValue = (double)args.OldValue;
            double newValue = (double)args.NewValue;
            if (oldValue != newValue)
            {
                target.OnMaximumChanged(oldValue, newValue);
            }
        }

        protected virtual void OnMaximumChanged(double oldValue, double newValue)
        {
        }


        /// <summary>
        /// 获取或设置Minimum的值
        /// </summary>  
        public double Minimum
        {
            get { return (double)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }

        /// <summary>
        /// 标识 Minimum 依赖属性。
        /// </summary>
        public static readonly DependencyProperty MinimumProperty =
            DependencyProperty.Register("Minimum", typeof(double), typeof(RangeControl), new PropertyMetadata(double.NegativeInfinity, OnMinimumChanged));

        private static void OnMinimumChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            RangeControl target = obj as RangeControl;
            double oldValue = (double)args.OldValue;
            double newValue = (double)args.NewValue;
            if (oldValue != newValue)
                target.OnMinimumChanged(oldValue, newValue);
        }

        protected virtual void OnMinimumChanged(double oldValue, double newValue)
        {
        }


        /// <summary>
        /// 获取或设置StepFrequency的值
        /// </summary>  
        public double StepFrequency
        {
            get { return (double)GetValue(StepFrequencyProperty); }
            set { SetValue(StepFrequencyProperty, value); }
        }

        /// <summary>
        /// 标识 StepFrequency 依赖属性。
        /// </summary>
        public static readonly DependencyProperty StepFrequencyProperty =
            DependencyProperty.Register("StepFrequency", typeof(double), typeof(RangeControl), new PropertyMetadata(0.01d, OnStepFrequencyChanged));

        private static void OnStepFrequencyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            RangeControl target = obj as RangeControl;
            double oldValue = (double)args.OldValue;
            double newValue = (double)args.NewValue;
            if (oldValue != newValue)
            {
                var f = (float)newValue;
                var value = Regex.Match(f.ToString(), @"(?<=\.)\d+").Value;
                target.stepFrequency = $"f{value.Length}";
                target.OnStepFrequencyChanged(oldValue, newValue);
            }
        }

        protected virtual void OnStepFrequencyChanged(double oldValue, double newValue)
        {
        }



        #region ProviderGener     
        /// <summary>
        /// 获取或设置ProviderGener的值
        /// </summary>  
        public Object ProviderGener
        {
            get { return (Object)GetValue(ProviderGenerProperty); }
            set { SetValue(ProviderGenerProperty, value); }
        }

        /// <summary>
        /// 标识 ProviderGener 依赖属性。
        /// </summary>
        public static readonly DependencyProperty ProviderGenerProperty =
            DependencyProperty.Register("ProviderGener", typeof(Object), typeof(RangeControl), new PropertyMetadata(0, OnProviderGenerChanged));

        private static void OnProviderGenerChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            RangeControl target = obj as RangeControl;
            Object oldValue = (Object)args.OldValue;
            Object newValue = (Object)args.NewValue;
            if (oldValue != newValue)
                target.OnProviderGenerChanged(oldValue, newValue);
        }

        protected virtual void OnProviderGenerChanged(Object oldValue, Object newValue)
        {
        }


        #region ExproterGenre     
        /// <summary>
        /// 获取或设置ExproterGenre的值
        /// </summary>  
        public Object ExproterGenre
        {
            get { return (Object)GetValue(ExproterGenreProperty); }
            set { SetValue(ExproterGenreProperty, value); }
        }

        /// <summary>
        /// 标识 ExproterGenre 依赖属性。
        /// </summary>
        public static readonly DependencyProperty ExproterGenreProperty =
            DependencyProperty.Register("ExproterGenre", typeof(Object), typeof(RangeControl), new PropertyMetadata(0, OnExproterGenreChanged));

        private static void OnExproterGenreChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            RangeControl target = obj as RangeControl;
            Object oldValue = (Object)args.OldValue;
            Object newValue = (Object)args.NewValue;
            if (oldValue != newValue)
                target.OnExproterGenreChanged(oldValue, newValue);
        }

        protected virtual void OnExproterGenreChanged(Object oldValue, Object newValue)
        {
        }
        #endregion

        #endregion



        #region IsChildVisible     
        /// <summary>
        /// 获取或设置IsChildVisible的值
        /// </summary>  
        public Visibility IsChildVisible
        {
            get { return (Visibility)GetValue(IsChildVisibleProperty); }
            set { SetValue(IsChildVisibleProperty, value); }
        }

        /// <summary>
        /// 标识 IsChildVisible 依赖属性。
        /// </summary>
        public static readonly DependencyProperty IsChildVisibleProperty =
            DependencyProperty.Register("IsChildVisible", typeof(Visibility), typeof(RangeControl), new PropertyMetadata(Visibility.Visible, OnIsChildVisibleChanged));

        private static void OnIsChildVisibleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            RangeControl target = obj as RangeControl;
            Visibility oldValue = (Visibility)args.OldValue;
            Visibility newValue = (Visibility)args.NewValue;
            if (oldValue != newValue)
                target.OnIsChildVisibleChanged(oldValue, newValue);
        }

        protected virtual void OnIsChildVisibleChanged(Visibility oldValue, Visibility newValue)
        {
        }
        #endregion



        #endregion

        protected string stepFrequency = "f2";
        protected Panel controlContainer;
        protected ProviderDropControl providerDrop;
        protected ExporterDragControl exporterDrag;
        protected ContentPresenter headerPresenter;

        protected string exproterValueName;
        /// <summary>
        /// 构造函数
        /// </summary>
        public RangeControl()
        {
            this.DefaultStyleKey = typeof(RangeControl);
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            CreateProviderAndExproterControl();
            GetProviderAndExproterControl();
        }

        protected void GetProviderAndExproterControl()
        {
            if(providerDrop == null)
            {
                providerDrop = GetTemplateChildFormName<ProviderDropControl>(nameof(providerDrop));
            }

            if(exporterDrag == null)
            {
                exporterDrag = GetTemplateChildFormName<ExporterDragControl>(nameof(exporterDrag));
            }
            if(headerPresenter == null)
            {
                headerPresenter = GetTemplateChildFormName<ContentPresenter>(nameof(headerPresenter));

            }

            if (providerDrop != null)
            {
                TemplateControlUtil.CreateBinding(this, "", nameof(IsProvider), providerDrop, VisibilityProperty);
                TemplateControlUtil.CreateBinding(this, "", nameof(ProviderGener), providerDrop, ProviderDropControl.TypeProperty);

                providerDrop.AllowDrop = true;
                providerDrop.DragEnter += providerDrop_DragEnter;
                providerDrop.Drop += providerDrop_Drop;
            }
            if (exporterDrag != null)
            {
                exporterDrag.CanDrag = true;
                TemplateControlUtil.CreateBinding(this, "", nameof(IsExporter), exporterDrag, VisibilityProperty);
                TemplateControlUtil.CreateBinding(this, "", nameof(ExproterGenre), exporterDrag,ExporterDragControl.TypeProperty);
                exporterDrag.DragStarting += exporterDrag_DragStarting;
            }

            if(headerPresenter != null)
            {
                TemplateControlUtil.CreateBinding(this, "", nameof(Header), headerPresenter, ContentPresenter.ContentProperty);
            }
        }

        private void CreateProviderAndExproterControl()
        {
            controlContainer = GetTemplateChildFormName<Panel>(nameof(controlContainer));
            if (controlContainer != null)
            {
                exporterDrag = new ExporterDragControl() { CanDrag = true, Name = "exporterDrag" };
     
                providerDrop = new ProviderDropControl()
                {
                    AllowDrop = true,
                    Name = "providerDrop"
                };

                var column = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };
                var column1 = new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) };


                Grid grid = new Grid();
                grid.ColumnDefinitions.Add(column);
                grid.ColumnDefinitions.Add(column1);

                Grid.SetColumn(providerDrop, 0);
                Grid.SetColumn(exporterDrag, 1);
                grid.Children.Add(providerDrop);
                grid.Children.Add(exporterDrag);

                 headerPresenter = new ContentPresenter() { Name = "headerPresenter" };
                controlContainer.Children.Insert(0, grid);
                controlContainer.Children.Insert(0, headerPresenter);
            }

        }

        public void SetProviderType(object type)
        {
            if (providerDrop != null)
            {
                providerDrop.Type = type;
            }
        }

        public void SetExporterType(object type)
        {
            if (exporterDrag != null)
            {
                exporterDrag.Type = type;
            }
        }

        #region 输出数据控件



        private void exporterDrag_DragStarting(UIElement sender, DragStartingEventArgs args)
        {
            OnDragExportInvoke();
            OnexporterDrag(sender, args);
        }

        protected override void OnIsExporterChanged(bool oldValue, bool newValue)
        {
            if (exporterDrag != null)
            {
                exporterDrag.Visibility = newValue ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        #endregion

        #region  接收数据控件

        /// <summary>
        /// 进入接受范围
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void providerDrop_DragEnter(object sender, DragEventArgs e)
        {
            OnProviderEnter(sender, e);
        }

        /// <summary>
        /// 数据降下来了
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void providerDrop_Drop(object sender, DragEventArgs e)
        {
            OnProviderDrop(sender, e);
        }

        protected override void OnIsProviderChanged(bool oldValue, bool newValue)
        {
            if (providerDrop != null)
            {
                providerDrop.Visibility = newValue ? Visibility.Visible : Visibility.Collapsed;
            }
        }
        #endregion

        protected abstract void OnexporterDrag(UIElement sender, DragStartingEventArgs args);


        protected abstract void OnProviderEnter(object sednder, DragEventArgs e);


        protected abstract void OnProviderDrop(object sender, DragEventArgs e);
      


        public override void Destroy()
        {
            base.Destroy();
            oneConnectElement = null;
        }

        public override void RemoveProvider(ConnectLineUIElement connectElement)
        {
            //删除连接线
            RemoveExportoneConnectElement(connectElement);
            
            if (ListExportoneConnectElement.Count > 0)
            {
                (exporterDrag as ExporterDragControl)?.SetDeConnectState();
            }
        }
        public override void RemoveExport(ConnectLineUIElement connectElement)
        {
            oneConnectElement = null;
            //断开接收
            providerDrop.SetDeConnectState();
            RemoveProvideroneConnectElement(connectElement);
        }

        protected abstract override void Timer_Tick(object sender, object e);
    

    }
}
